﻿PuppetPlay.StageScenery = (function(){
    var stage = null;
    
    var backgroundLayer = null;
    
    var puppetLayer = null;
    
    var toolLayer = null;

    var linkLayer = null;

    var appBar = null;

    var roleLeft = null;

    var roleRight = null;
	
	var setting = PuppetPlay.Setting;
    
    return {
        init: function(ct){
            stage = new Kinetic.Stage({
                container: ct,
                width: document.documentElement.clientWidth,
                height: document.documentElement.clientHeight
            });   
    
            backgroundLayer = new Kinetic.Layer({
                listening: false
            });
            stage.add(backgroundLayer);
            
            toolLayer = new Kinetic.Layer({
                listening: false
            });
            
            stage.add(toolLayer);
            puppetLayer = new Kinetic.Layer({
                listening: false
            });
            stage.add(puppetLayer);

  
            
            appBar = new PuppetPlay.AppBar({
                x: 0,
                y: stage.getHeight() - setting.TOOL_BAR_HEIGHT,
                width: stage.getWidth(),
                height: setting.TOOL_BAR_HEIGHT,
                leftPointerDrawFunc: function (context) {
                    var s = roleLeft.getBodyJointPoint();
                    var t = this.getAbsolutePosition();
					t.x += 63;
					t.y += 80;
                    var angle;
                    var radius = setting.ROTATIONBOARD_RADIUS;

                    if (s.x == t.x) {
                        angle = Math.PI / 2;
                    } else {
                        angle = Math.atan((t.y - s.y) / (s.x - t.x));

                    }


                    context.beginPath();
                    var p0 = t;
                    var p1 = {
                        x: Math.round(63 + radius * Math.cos(angle) * (angle > 0 ? 1 : -1)),
                        y: Math.round(80 + -Math.abs(radius * Math.sin(angle)))
                    };
                    context.moveTo(63, 80);
                    context.lineTo(p1.x, p1.y)
                    context.closePath();
                    this.stroke(context);
                },
                rightPointerDrawFunc: function (context) {
                    var s = roleRight.getBodyJointPoint();
                    var t = this.getAbsolutePosition();
					t.x += 63;
					t.y += 80;
                    var angle;
                    var radius = setting.ROTATIONBOARD_RADIUS;

                    if (s.x == t.x) {
                        angle = Math.PI / 2;
                    } else {
                        angle = Math.atan((t.y - s.y) / (s.x - t.x));

                    }


                    context.beginPath();
                    var p0 = t;
                    var p1 = {
                        x: 63 + radius * Math.cos(angle) * (angle > 0 ? 1 : -1),
                        y: 80 + -Math.abs(radius * Math.sin(angle))
                    };
                    context.moveTo(63, 80);
                    context.lineTo(p1.x, p1.y)
                    context.closePath();
                    this.stroke(context);
                },
                leftPulleyCallback: function (d) {
                    roleLeft.rotateLeftArm(d);
                    roleLeft.rotateRightArm(-d);
                },
                rightPulleyCallback: function (d) {
                    roleRight.rotateLeftArm(d);
                    roleRight.rotateRightArm(-d);
                },
				leftStickRotateCallback: function(deg){
				    if((roleLeft.getRotation() - deg > Math.PI / 6) || 
					        (roleLeft.getRotation() - deg < Math.PI / -6)){
					    return;
					}
				    roleLeft.rotate(-deg);
				},
				leftStickMoveCallback: function (moveXY) {
				    roleLeft.move(moveXY);
				},
				rightStickRotateCallback: function (deg) {
				    deg *= -1;
				    if ((roleRight.getRotation() + deg > Math.PI / 6) ||
					        (roleRight.getRotation() + deg < Math.PI / -6)) {
					    return;
					}
				    roleRight.rotate(deg);
				},
				rightStickMoveCallback: function (moveXY) {
				    roleRight.move(moveXY);
				}
            });  
            toolLayer.add(appBar);  
            toolLayer.toRfresh = true;


            linkLayer = new Kinetic.Layer({
                listening: false
            });
            stage.add(linkLayer);

            PuppetPlay.Background.renderTo(backgroundLayer);

            this._initLinkLayer();
        },
            
        _initLinkLayer: function () {
            linkLayer.add(new Kinetic.Shape({
                stroke: 'rgb(235,235,235)',
                strokeWidth: 1,
                drawFunc: function (context) {
                    context.beginPath();
                    var s = roleLeft.getRightArmJoinPoint();
                    var t = appBar.getLeftPulleyJointPoint(s.x, s.y);

                    if (t[0] >= t[2]) {
                        context.moveTo(t[0] - 1, t[1] - 1);
                    } else {
                        context.moveTo(t[2] - 1, t[3] - 1);
                    }
                    context.lineTo(s.x, s.y)
                    context.closePath();
                    this.stroke(context);
                }
            }));

            linkLayer.add(new Kinetic.Shape({
                stroke: 'rgb(235,235,235)',
                strokeWidth: 1,
                drawFunc: function (context) {
                    context.beginPath();
                    var s = roleRight.getLeftArmJoinPoint();
                    var t = appBar.getRightPulleyJointPoint(s.x, s.y);
                    if (t[0] < t[2]) {
                        context.moveTo(t[0] + 1, t[1] - 1);
                    } else {
                        context.moveTo(t[2] + 1, t[3] - 1);
                    }
                    context.lineTo(s.x, s.y)
                    context.closePath();
                    this.stroke(context);
                }
            }));
        },
        
        loadRoles: function () {

            var zoom = PuppetPlay.Util.getZoomFactor();

            roleLeft = new PuppetPlay.Puppet({
                rsName: 'puppet001',
                //x: 340 * zoom,
                //y: 162 * zoom,
                x: setting.MOVEHANDLE_CENTER_OFFSET_X,
                //y: 658 * zoom,
                y: document.documentElement.clientHeight - (768-658), //document.documentElement.clientHeight - PuppetPlay.Setting.TOOL_BAR_HEIGHT * zoom + PuppetPlay.Setting.MOVEHANDLE_CENTER_OFFSET_Y,
                face: "right"
            });
            puppetLayer.add(new Kinetic.Shape({
                stroke: 'rgb(235,235,235)',
                strokeWidth: 1,
                drawFunc: function (context) {
                    context.beginPath();
                    var s = roleLeft.getLeftArmJoinPoint();
                    var t = appBar.getLeftPulleyJointPoint(s.x, s.y);
                    if (t[0] < t[2]) {
                        context.moveTo(t[0] + 1, t[1] + 1);
                    } else {
                        context.moveTo(t[2] + 1, t[3] + 1);
                    }
                    context.lineTo(s.x, s.y)
                    context.closePath();
                    this.stroke(context);
                }
            }));

            roleRight = new PuppetPlay.Puppet({
                rsName: 'puppet002',
                x: document.documentElement.clientWidth - setting.MOVEHANDLE_CENTER_OFFSET_X,
                y: document.documentElement.clientHeight - (768 - 658),
                face: "left"
            });
            puppetLayer.add(new Kinetic.Shape({
                stroke: 'rgb(235,235,235)',
                strokeWidth: 1,
                drawFunc: function (context) {
                    context.beginPath();
                    var s = roleRight.getRightArmJoinPoint();
                    var t = appBar.getRightPulleyJointPoint(s.x, s.y);
                    if (t[0] > t[2]) {
                        context.moveTo(t[0] - 1, t[1] + 1 );
                    } else {
                        context.moveTo(t[2] - 1, t[3] + 1 );
                    }
                    context.lineTo(s.x, s.y)
                    context.closePath();
                    this.stroke(context);
                }
            }));

            //left control stick
            puppetLayer.add(new Kinetic.Shape({
                stroke: 'rgb(235,235,235)',
                strokeWidth: 6,
                drawFunc: function (context) {
                    context.beginPath();
                    var s = roleLeft.getBodyJointPoint();
                    var t = appBar.getLeftStickJointPoint();
                    var c;
                    if (s.x == t.x) {
                        c = {
                            x: t.x,
                            y: t.y - 25
                        };
                    } else {
                        var angle = Math.atan((t.y - s.y) / (s.x - t.x));
                        c = {
                            x: t.x + (angle > 0 ? 1 : -1) * 25 * Math.cos(angle),
                            y: t.y - (angle > 0 ? 1 : -1) * 25 * Math.sin(angle)
                        };
                    }

                    context.moveTo(c.x, c.y);
                    context.lineTo(s.x, s.y);
                    //console.log([s.x, s.y, t.x, t.y])
                    context.closePath();
                    this.stroke(context);
                }
            }));

            //right control stick
            puppetLayer.add(new Kinetic.Shape({
                stroke: 'rgb(235,235,235)',
                strokeWidth: 6,
                drawFunc: function (context) {
                    context.beginPath();
                    var s = roleRight.getBodyJointPoint();
                    var t = appBar.getRightStickJointPoint();
                    var c;
                    if (s.x == t.x) {
                        c = {
                            x: t.x,
                            y: t.y - 25
                        };
                    } else {
                        var angle = Math.atan((t.y - s.y) / (s.x - t.x));
                        c = {
                            x: t.x + (angle > 0 ? 1 : -1) * 25 * Math.cos(angle),
                            y: t.y - (angle > 0 ? 1 : -1) * 25 * Math.sin(angle)
                        };
                    }
                    context.moveTo(c.x, c.y);
                    context.lineTo(s.x, s.y);
                    //console.log([s.x, s.y, t.x, t.y])
                    context.closePath();
                    this.stroke(context);
                }
            }));

            puppetLayer.add(roleLeft);
            puppetLayer.add(roleRight);

            appBar.stick01.setAbsolutePosition({
                x: roleLeft.getAbsolutePosition().x,
                y: appBar.stick01.getAbsolutePosition().y
            });
            appBar.stick02.setAbsolutePosition({
                x: roleRight.getAbsolutePosition().x,
                y: appBar.stick02.getAbsolutePosition().y
            });
        },
        
        draw: function(){ 
            stage.draw();

            
            var that = this;
			var setting = PuppetPlay.Setting;
            if (!that.__refreshTimer) {
                var lastTime = Date.now();
                var fn = function () {
                    //if (appBar) console.log([appBar.pulley02.getAbsolutePosition().x, appBar.pulley02.getAbsolutePosition().y])
                    if(toolLayer.toRfresh){  
                        toolLayer.draw();

                        puppetLayer.draw();
                        linkLayer.draw();

                    }                
                    that.__refreshTimer = requestAnimFrame(fn);
					if(setting.DEBUG_MODE){
						var currentTime = Date.now();
						PuppetPlay.Util.log(Math.round(1000/(currentTime - lastTime)) + 'fps');
						lastTime = currentTime;
					}
                };
                fn();
            }
        },
        
        getStage: function(){
            return stage;
        }
    };

})();